package cn.openea.perpartner.meily.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.openea.perpartner.common.core.enums.RabbitEnums;
import cn.openea.perpartner.common.core.exception.ServiceException;
import cn.openea.perpartner.meily.rabbit.domain.BusinessDto;
import cn.openea.perpartner.meily.rabbit.factory.BusinessServiceFactory;
import cn.openea.perpartner.meily.rabbit.service.BusinessService;
import cn.openea.perpartner.meily.thirdparty.BpmSystemApi;
import cn.openea.perpartner.meily.web.entity.*;
import cn.openea.perpartner.meily.web.entity.dto.CustomerDTOFactory;
import cn.openea.perpartner.meily.web.entity.dto.EvaluatorPeopleDTOFactory;
import cn.openea.perpartner.meily.web.entity.dto.SyncBPMAddressDTO;
import cn.openea.perpartner.meily.web.entity.vo.CustomerRecommendVo;
import cn.openea.perpartner.meily.web.entity.vo.CustomerSearchVo;
import cn.openea.perpartner.meily.web.mapper.CustomerMapper;
import cn.openea.perpartner.meily.web.service.ICustomerService;
import cn.openea.perpartner.meily.web.service.IPersonalInfoService;
import cn.openea.perpartner.meily.web.service.IProviderService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.NonNull;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;


@Service("customerService")
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements ICustomerService, BusinessService {

    @Resource
    private BpmSystemApi bpmSystemApi;
    @Resource
    private IProviderService providerService;
    @Resource
    private IPersonalInfoService personalInfoService;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Override
    public List<Customer> selectListByVO(CustomerSearchVo searchVo) {
        searchVo.buildDateRangeParams();
        return baseMapper.selectListBySerchVO(searchVo);
    }

    @Override
    public Map<String, Integer> statisticsCustomerTypeQuantity(CustomerSearchVo searchVo) {
        searchVo.buildDateRangeParams();
        return baseMapper.countCustomerTypeQuantity(searchVo);
    }

    @Override
    public List<Customer> selectByIds(List<String> batchIds) {
        if (batchIds == null || batchIds.isEmpty()) {
            return new ArrayList<>();
        }
        return baseMapper.selectBatchIds(batchIds);
    }

    @Override
    public Customer findByUserId(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        return baseMapper.selectOne(new LambdaQueryWrapper<Customer>().eq(Customer::getUserId, userId));
    }

    /**
     * 更新个人基本信息（新增或修改）
     *
     * @param customer
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(Customer customer) {

        if (!saveOrUpdate(customer)) {
            throw new ServiceException("更新个人基本信息出错了！");
        }

        /**
         * 第2步 同步收货地址到BPM的收货地址记录表（Archives_Address）
         */
        // 地址不为空，才需要同步
        if (customer.checkAddressIsNotBlank()) {
            bpmSystemApi.syncAddress(SyncBPMAddressDTO.builder()
                    .userId(customer.getUserId())
                    .userName(customer.getUserName())
                    .realName(customer.getRealName())
                    .phoneNumber(customer.getPhoneNumber())
                    .region(customer.getRegion())
                    .streetVillage(customer.getStreetVillage())
                    .address(customer.getAddress())
                    .build());
        }
        return true;
    }

    /**
     * 小程序-判断个人基本信息是否完善
     *
     * @param userId
     * @return
     */
    @Override
    public boolean finish(String userId) {

        LambdaQueryWrapper<Customer> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Customer::getUserId, userId);
        Customer customer = getOne(wrapper);

        if (customer == null || BeanUtil.isEmpty(customer)) {
            return false;
        }
        // 遍历JSONObject时，跳过以下字段
        String FieldNames = "id,createTime,updateTime,openid,unionid,subscriptionOpenid,isSubscribed,providerId,evaluatorId";

        JSONObject infoObject = JSON.parseObject(JSON.toJSONString(customer), JSONObject.class);

        // 遍历JSONObject
        Iterator iter = infoObject.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) iter.next();
            String key = entry.getKey();
            if (FieldNames.contains(key)) {
                continue;
            }

            if (entry.getValue() != null) {
                String value = entry.getValue();
                if (StrUtil.isBlank(value)) {
                    return false;
                }
            } else {
                return false;
            }
        }

        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCustomerByDTO(@NonNull CustomerDTOFactory.CustomerAllInfoDTO dto) {
        CustomerDTOFactory.CustomerBasicInfoDTO customerBasicInfoDTO = dto.getCustomerBasicInfoDTO();
        if (customerBasicInfoDTO != null && customerBasicInfoDTO.getId() != null) {
            // 修改个人资料信息
            Customer customer = new Customer();
            BeanUtils.copyProperties(customerBasicInfoDTO, customer);
            saveOrUpdate(customer);
            // 地址不为空，同步bpm中的数据
            if (customer.checkAddressIsNotBlank()) {
                bpmSystemApi.syncAddress(SyncBPMAddressDTO.builder()
                        .userId(customer.getUserId())
                        .userName(customer.getUserName())
                        .realName(customer.getRealName())
                        .phoneNumber(customer.getPhoneNumber())
                        .region(customer.getRegion())
                        .streetVillage(customer.getStreetVillage())
                        .address(customer.getAddress())
                        .build());
            }
        }
        Provider providerDTO = dto.getProviderDTO();
        if (providerDTO != null && providerDTO.getId() != null) {
            // 修改区域服务商
            providerService.saveOrUpdate(providerDTO);
        }
        EvaluatorPeopleDTOFactory.EvaluatorPeopleBasicInfoDTO evaluatorPeopleBasicInfoDTO = dto.getEvaluatorPeopleBasicInfoDTO();
        if (evaluatorPeopleBasicInfoDTO != null && StringUtils.isNotBlank(evaluatorPeopleBasicInfoDTO.getId())) {
            // 修改测评师信息
            PersonalInfo personalInfo = new PersonalInfo();
            BeanUtils.copyProperties(evaluatorPeopleBasicInfoDTO, personalInfo);
            personalInfoService.saveOrUpdate(personalInfo);
        }
    }

    /**
     * 为你推荐
     * 类型。0推荐资源、1测评师、2商超便利店、3餐饮店铺、4团购驿站、5线上服务商
     * @param vo
     * @return
     */
    @Override
    public List<Customer> recommend(CustomerRecommendVo vo){

        // 查询类型
        String searchType = vo.getSearchType();

        // 返回结果
        List<CustomerRecommend> list = new ArrayList<>();
        MPJLambdaWrapper<Customer> wrapper = new MPJLambdaWrapper<>();
        wrapper.selectAll(Customer.class);
        if(StrUtil.isNotBlank(searchType) && !"0".equals(searchType) && !"1".equals(searchType)){
            // 连表查询
            wrapper.leftJoin(Provider.class, Provider::getUserId, Customer::getUserId);
        }

        // 真实姓名不为空
        wrapper.isNotNull(Customer::getRealName);
        wrapper.ne(Customer::getRealName, "");

        // 性别不为空
        wrapper.isNotNull(Customer::getSex);
        wrapper.ne(Customer::getSex, "");

        // 年龄层不为空
        wrapper.isNotNull(Customer::getAgeGroup);
        wrapper.ne(Customer::getAgeGroup, "");

        // 所属地区不为空
        wrapper.isNotNull(Customer::getRegion);
        wrapper.ne(Customer::getRegion, "");

        // 关键字搜索
        if (StrUtil.isNotBlank(vo.getSearchStr())) {
            wrapper.and(wrap -> wrap.like(Customer::getUserName, vo.getSearchStr())
                    .or().like(Customer::getRegion, vo.getSearchStr()));
        }

        // 为你推荐（目前只能随机取，没错刷新可能存在重复）
        if("0".equals(searchType)){
            wrapper.last(" order by rand() ");

        } else if("1".equals(searchType)){
            // 测评师
            wrapper.isNotNull(Customer::getEvaluatorId);
            wrapper.ne(Customer::getEvaluatorId, "");
            wrapper.orderByDesc(Customer::getRealName);

        } else if("2".equals(searchType)){
            // 商超便利店：获取区域服务商的店铺类型为“便利店”的用户，头像用店铺头像，昵称=店铺名称，身份=区域服务商
            wrapper.isNotNull(Customer::getProviderId);
            wrapper.ne(Customer::getProviderId, "");
            wrapper.eq(Provider::getStoreType, "便利店");
            wrapper.orderByDesc(Customer::getRealName);

        } else if("3".equals(searchType)){
            // 餐饮店铺：获取区域服务商的店铺类型为“餐饮、其他店铺”的用户，头像用店铺头像，昵称=店铺名称，身份=餐饮店铺
            wrapper.isNotNull(Customer::getProviderId);
            wrapper.ne(Customer::getProviderId, "");
            wrapper.in(Provider::getStoreType, "餐饮","其他店铺");
            wrapper.orderByDesc(Customer::getRealName);

        } else if("4".equals(searchType)){
            // 团购驿站：获取区域服务商的店铺类型为“团购点、菜鸟驿站”的用户，头像用店铺头像，昵称=店铺名称，身份=团购驿站
            wrapper.isNotNull(Customer::getProviderId);
            wrapper.ne(Customer::getProviderId, "");
            wrapper.in(Provider::getStoreType, "团购点","菜鸟驿站");
            wrapper.orderByDesc(Customer::getRealName);

        } else if("5".equals(searchType)){
            // 线上服务商：获取区域服务商的店铺类型为“个人”的用户，头像=店铺头像，昵称=店铺名称
            wrapper.isNotNull(Customer::getProviderId);
            wrapper.ne(Customer::getProviderId, "");
            wrapper.eq(Provider::getStoreType, "个人");
            wrapper.orderByDesc(Customer::getRealName);

        }

        return baseMapper.selectList(wrapper);
    }

    /**
     * 组装业务数据
     * @param customerList
     * @param searchType
     * @return
     */
    @Override
    public List<CustomerRecommend> assemblyData(List<Customer> customerList, String searchType) {

        List<CustomerRecommend> list = new ArrayList<>();

        // 获取区域服务商数据
        List<String> userIdList = new ArrayList<>();
        for (Customer customer : customerList){
            if(StrUtil.isNotBlank(customer.getUserId())){
                userIdList.add(customer.getUserId());
            }
        }

        List<Provider> providerList = new ArrayList<>();
        if(userIdList.size() > 0){
            LambdaQueryWrapper<Provider> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Provider::getUserId, userIdList);
            providerList = providerService.list(wrapper);
        }

        // 遍历列表，组装业务数据
        for(Customer customer : customerList) {
            CustomerRecommend vo1 = new CustomerRecommend();
            BeanUtil.copyProperties(customer, vo1, true);

            Provider provider = new Provider();
            if(providerList.size() > 0){
                int index = getIndexByUserId( providerList, customer.getUserId());// 数组下标
                if(index >= 0){
                    provider = providerList.get(index);
                }
            }

            if("0".equals(searchType)){
                // 需要判断是否当前用户的身份
                if(StrUtil.isNotBlank(vo1.getEvaluatorId())){
                    vo1.setIdentityType("测评师");
                } else if (StrUtil.isNotBlank(vo1.getProviderId())){
                    vo1.setIdentityType("区域服务商");
                    if(BeanUtil.isNotEmpty(provider)){
                        if("餐饮".equals(provider.getStoreType()) || "其他店铺".equals(provider.getStoreType())){
                            // 餐饮店铺：获取区域服务商的店铺类型为“餐饮、其他店铺”的用户，头像用店铺头像，昵称=店铺名称，身份=餐饮店铺
                            vo1.setIdentityType("餐饮店铺");
                        } else if("团购点".equals(provider.getStoreType()) || "菜鸟驿站".equals(provider.getStoreType())){
                            // 团购驿站：获取区域服务商的店铺类型为“团购点、菜鸟驿站”的用户，头像用店铺头像，昵称=店铺名称，身份=团购驿站
                            vo1.setIdentityType("团购驿站");
                        }
                    }
                }

            } else if("1".equals(searchType)){
                vo1.setIdentityType("测评师");
            }  else if("2".equals(searchType)){
                vo1.setIdentityType("区域服务商");
            } else if("3".equals(searchType)){
                vo1.setIdentityType("餐饮店铺");
            } else if("4".equals(searchType)){
                vo1.setIdentityType("团购驿站");
            } else if("5".equals(searchType)){
                vo1.setIdentityType("区域服务商");
            }

            if(BeanUtil.isNotEmpty(provider)){
                if("2".equals(searchType) || "3".equals(searchType) || "4".equals(searchType) || "5".equals(searchType)){
                    if(StrUtil.isNotBlank(provider.getStoreName())){
                        vo1.setUserName(provider.getStoreName());
                    }
                    if(StrUtil.isNotBlank(provider.getStoreAvatar())){
                        vo1.setAvatarUrl(provider.getStoreAvatar());
                    }
                }
            }

            list.add(vo1);
        }

        /**
         * 将用户昵称最后一个字处理成*号
         */
        for(CustomerRecommend recommend : list){
            if(StrUtil.isNotBlank(recommend.getUserName())){
                String userName = recommend.getUserName();
                String newUserName = userName.replace(userName.charAt(userName.length()-1)+"", "*");
                recommend.setUserName(newUserName);
            }
        }

        return list;
    }

    private int getIndexByUserId(List<Provider> providerList, String userId) {
        for (int i = 0; i < providerList.size(); i++) {
            if (userId.equals(providerList.get(i).getUserId())) {
                return i;
            }
        }
        return -1; // 如果未找到匹配值，则返回-1表示未找到
    }


    @Override
    public TimerTask execute(BusinessDto business) {

        return new TimerTask() {
            @Override
            public void run() {
                //查询所有手机号不为空的用户
                LambdaQueryWrapper<Customer> wrapper = new LambdaQueryWrapper<>();
                wrapper.ne(Customer::getPhoneNumber,"");
                wrapper.isNotNull(Customer::getPhoneNumber);
                List<Customer> userList = list(wrapper);
                //为防止消息过大，分批发送
                int batchSize = 1000;
                int totalSize = userList.size();
                for (int i = 0; i < totalSize; i += batchSize) {
                    int endIndex = Math.min(i + batchSize, totalSize);
                    List<Customer> subList = userList.subList(i, endIndex);
                    List<JSONObject> sendToList = new ArrayList<>();
                    subList.forEach(user -> {
                        JSONObject sendTo = new JSONObject();
                        sendTo.put("sendTo",user.getRealName());
                        sendTo.put("phoneNumber",user.getPhoneNumber());
                        sendToList.add(sendTo);
                    });
                    JSONObject object = business.getParams();
                    object.put("sendParam",sendToList);
                    //将消息发送回
                    String exchange = RabbitEnums.COMPONET_SMS.getExchange();
                    String routeKey = RabbitEnums.COMPONET_SMS.getRoutingKey();
                    rabbitTemplate.convertAndSend(exchange, routeKey, object, message -> {
                        message.getMessageProperties().setHeader("x-delay", 0);
                        return message;
                    });;
                }
            }
        };
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        BusinessServiceFactory.register("customerService",this);
    }
}
